package demo2;

//      抽象类
//      1.包含抽象方法的类 叫做抽象类
//      2.什么是抽象方法 一个没有具体实现的方法 被abstract修饰
//      3.抽象类是不可以被实例化的 就是不能通过new关键字实例化一个对象
//      虽然不能被实例化 但是可以发生向上转型main1 可以向上转型也可以实现多态
//      4.因为不能被实例化 使用这个抽象类只能被继承
//      5.抽象类当中 也可以包含 普通类一样的成员和方法
//      6.一个普通类继承了一个抽象类 那么这个普通类当中 需要重写这个抽象类的所有抽象方法
//      如果没重写 就会报错
//      7.抽象类最大的作用 为了被继承
//      8.一个抽象类A 如果继承了一个抽象类B 那么这个抽象类 可以不实现抽象父类的抽象方法（下面的A 和B类）
//      9.结合第八点 当A类再次被一个普通类继承后 那么A类和B类这两个抽象类当中的抽象方法 必须被重写
//      10.抽象类不能被final修饰 抽象方法也不能被final修饰
abstract class Shape {
    public int a = 9;

    public void func(){
        System.out.println("调用父类方法");
    }
//    如果你不想给父类draw方法具体的实现 可以使用abstract(抽象)修饰
//    如果你的方法被abstract修饰 那么你的类也要变成抽象类(abstract)
//    这样才不会报红
    public abstract void draw();
}

class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("♦");
    }
}
class Flower extends Shape{
    @Override
    public void draw() {
        System.out.println("❀" + a);
        super.func();//没报错 也可以不加super.那会先在当前类寻找 没找到在去父类寻找
    }
//    super.func();//报错
//    super.a;//报错
//    1.super只能出现在实例方法和构造方法中
//    2.super的语法是 super. 和 super()
//    3.super不能出现在静态方法中
//    4.super大部分情况是可以省略的
//    5.super.不能省略的时候
//      this指向的是什么 是当前对象自己 super和this类似 它指向当前对象自己的
//      父类型特征(也就是继承过来的那些东西)

//    super和this区别
//      1.this可以看做一个引用变量，保存了该对象的地址，是当前对象整体，而super代表的是父类型特征，是子类局部的一些东西，
//      这些继承过来的东西已经在子类里面了，你可以输出整体this，但不能输出父类型特征super。因为super指向的东西不是一个整体，没法打印输出。
//      2.this和super都只能在对象内部使用。
//      this代表当前对象本身，super代表当前对象的父类型特征；super是this的一部分。
//      3.this. 是一个实例对象内部为了区分实例变量和局部变量。
//      而super. 是一个实例对象为了区分是子类的成员还是父类的成员。
//      父类有，子类也有，子类想访问父类的，super. 不能省略。
//      4.当子类的构造方法内第一行没有出现“super()”时，系统会默认给它加上无参数的"super()"方法。
//      5.this()和super()都只能出现在构造方法的第一行，故this()和super()方法不能共存，当一个类的构造方法第一行中没有this()，也没有super()，系统默认有super()方法
}
abstract class A extends Shape{
    public abstract void funcA();
}
class B extends A{
    @Override
    public void funcA() {
        super.func();
    }
    @Override
    public void draw() {
    }
}


public class Test {
    public static void drawMap(Shape shape) {
        shape.draw();
    }
    public static void main(String[] args) {
//        Shape shape = new Shape();//这样会报错

        Shape shape1 = new Rect();
        Shape shape2 = new Flower();
        drawMap(shape1);
        drawMap(shape2);
    }
}
